package com.archermind.boc.dal.business.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.archermind.boc.Logger;
import com.archermind.boc.dal.business.IDispatch;
import com.archermind.boc.dal.business.ISocketException;
import com.archermind.boc.dal.business.Icommision;
import com.archermind.boc.dal.business.file.IZhiWenHelper;
import com.archermind.boc.dal.business.file.impl.ZhiWenHelper;
import com.archermind.boc.dal.business.service.UserService;
import com.archermind.boc.dal.business.support.DispatchSupport;
import com.archermind.boc.domain.Auth;
import com.archermind.boc.domain.BankNet;
import com.archermind.boc.domain.Biz;
import com.archermind.boc.domain.BizStatus;
import com.archermind.boc.domain.BizTimeout;
import com.archermind.boc.domain.IQ;
import com.archermind.boc.domain.Message;
import com.archermind.boc.domain.Presence;
import com.archermind.boc.domain.Register;
import com.archermind.boc.domain.User;
import com.archermind.boc.ehcache.EhcacheInterface;
import com.archermind.boc.ehcache.UserCache;
import com.archermind.boc.ehcache.UserEhcacheImpl;
import com.archermind.boc.ehcache.UserStatus;
import com.archermind.boc.login.LoginMode;
import com.archermind.boc.login.LoginResponse;
import com.archermind.boc.login.LoginUtil;
import com.archermind.boc.socket.out.IBocSocketWriter;
import com.archermind.boc.utility.BizHelper;
import com.archermind.boc.xml.ApplicationContextFactory;

public class DispatchImpl implements IDispatch {
	private Logger log = Logger.getLogger(DispatchImpl.class.getName());
	private static final String KEY_ACCPET = "accept";
	private static final String KEY_REJECT = "reject";
	private static final String KEY_CANCEL = "cancel";
	private IBocSocketWriter bocSocketWriter;
	private Icommision commision;
	private ISocketException socketExceptionImpl;
	private BizHelper bizHelper;

	public BizHelper getBizHelper() {
		return bizHelper;
	}

	public void setBizHelper(BizHelper bizHelper) {
		this.bizHelper = bizHelper;
	}

	public ISocketException getSocketExceptionImpl() {
		return socketExceptionImpl;
	}

	public void setSocketExceptionImpl(ISocketException socketExceptionImpl) {
		this.socketExceptionImpl = socketExceptionImpl;
	}

	public IBocSocketWriter getBocSocketWriter() {
		return bocSocketWriter;
	}

	public void setBocSocketWriter(IBocSocketWriter bocSocketWriter) {
		this.bocSocketWriter = bocSocketWriter;
	}

	public void dispatch(Auth auth) {
		String base64 = auth.getAuth();
		String str = LoginUtil.decodedString(base64);
		UserService service = new UserService();
		LoginResponse response = new LoginResponse();
		User user = null;
		response.setSessionID(auth.getSessionID());

		if (LoginMode.PLAIN.equals(auth.getMechanism())) {
			String[] strArray = LoginUtil.ParseUser(str);
			if (strArray != null && strArray.length == 2) {
				try {
					String loginName = strArray[0];
					boolean isExit = service.IsExistByLogName(loginName);
					if (isExit) {
						user = service.getUser(strArray[0], strArray[1]);
					} else {
						String msg = "<error>账户不存在!</error>";
						response.setMessage(msg);
						bocSocketWriter.write(response);
						return;
					}
				} catch (Exception e) {
					String message = "<error>登录方式不正确或数据库连接异常!</error>";
					response.setMessage(message);
					bocSocketWriter.write(response);
					return;
				}
			}
			dealUser(user, auth);
			response = LoginUtil.loginedMessage(user);
		} else if (LoginMode.ZHI_WEN.equals(auth.getMechanism())) {
			try {
				boolean is = service.IsExistByLogName(str);
				if (is) {
					user = service.findUserByByLogName(str);
					response = LoginUtil.sendMessage(user);
				} else {
					String msg = "<error>账户不存在!</error>";
					response.setMessage(msg);
					bocSocketWriter.write(response);
					return;
				}
			} catch (Exception e) {
				String message = "<error>登录方式不正确或数据库连接异常!</error>";
				response.setMessage(message);
				bocSocketWriter.write(response);
				return;
			}
			dealUser(user, auth);
			response = LoginUtil.sendMessage(user);
		}
		response.setSessionID(auth.getSessionID());
		bocSocketWriter.write(response);
	}

	public void dealUser(User user, Auth auth) {
		// 如果usercache中不存在则 新增，否则修改sessionid
		if (user != null) {
			log.severe("[DispatchImpl] " + user.getUserid() + ":"
					+ user.getLoginName() + "已经登录了!");
			EhcacheInterface ei = new UserEhcacheImpl();
			UserCache uca = ei.getUserCacheById(user.getUserid());
			if (uca != null) {
				// 如果同一个人重新登录，则清除他上次登录时所做的业务，同时把他从缓存池清除。
				String sessionID = uca.getSessionID();
				socketExceptionImpl.stocketException(sessionID);
				uca.setSessionID(auth.getSessionID());
			}

			UserCache uc = new UserCache();
			uc.setIsBusy(UserStatus.USER_LEISURE);
			uc.setStatus(UserStatus.USER_SIGNOUT);
			uc.setRole(user.getRole());
			uc.setUserid(user.getUserid());
			uc.setNetworkIdentify(user.getBankNet().getNetId());
			uc.setSessionNum(0);
			uc.setSessionID(auth.getSessionID());
			uc.setLoginName(user.getLoginName());
			uc.setRealName(user.getRealName());
			ei.addElement(uc);
		}
	}

	public void register(IQ iq) {
		Register reg = iq.getRegister();
		Register newReg = new Register();
		UserService service = new UserService();
		String success; // 注册成功标志
		String error; // 注册失败标志
		IZhiWenHelper helper = ZhiWenHelper.getInstance();

		if (reg != null) {
			HashMap<String, List<String>> map = reg.getX();
			if (map != null && map.size() > 0) {
				User user = new User();
				BankNet bn = new BankNet();
				user.setLoginName(map.get("loginName").get(0));
				if ("pwd".equals(reg.getType())) {
					user.setPassword(map.get("password").get(0));
				} else if ("zw".equals(reg.getType())) {
					user.setPassword(helper.write(map.get("password").get(0),
							iq.getSessionID()));
				}
				bn.setNetId(map.get("netNum").get(0));
				user.setBankNet(bn);
				user.setRealName(map.get("realName").get(0));
				user.setRole(map.get("role").get(0));

				log.severe("[DispatchImpl] " + user.getUserid() + ":"
						+ user.getLoginName() + "开始注册了!");

				map.remove("password");
				newReg.setX(map);
				// 判断用户的角色是否合法
				if (UserStatus.USER_OPERATER.equals(user.getRole())
						|| UserStatus.USER_GRANT.equals(user.getRole())) {

					// 判断 登录名是否存在:false代表不存在，true代表存在。
					boolean isExist = service.IsExistByLogName(map.get(
							"loginName").get(0));
					if (isExist == false) {
						boolean isSucess = service.userAdded(user);
						// 注册成功
						if (isSucess == true) {
							log.severe("[DispatchImpl] " + user.getUserid()
									+ ":" + user.getLoginName() + "注册成功了!");
							success = "OK,注册成功!";
							newReg.setSuccess(success);

							// 注册失败
						} else {
							log.severe("[DispatchImpl] " + user.getUserid()
									+ ":" + user.getLoginName() + "注册失败!");
							error = "没有这个网点号,请重新注册!";
							newReg.setError(error);
							if ("zw".equals(reg.getType())) {
								helper.delFile(user.getPassword());
							}
						}

					} else {
						log.severe("[DispatchImpl] " + user.getUserid() + ":"
								+ user.getLoginName() + "注册失败!");
						error = "用户名已存在,请重新注册!";
						newReg.setError(error);
						if ("zw".equals(reg.getType())) {
							helper.delFile(user.getPassword());
						}
					}
				} else {
					log.severe("[DispatchImpl] " + user.getUserid() + ":"
							+ user.getLoginName() + "注册失败!");
					error = "用户的角色不合法，请重新注册!";
					newReg.setError(error);
					if ("zw".equals(reg.getType())) {
						helper.delFile(user.getPassword());
					}
				}
			}
		}
		iq.setRegister(newReg);
		bocSocketWriter.write(iq);
	}

	@SuppressWarnings("unchecked")
	public void dispatch(IQ iq) {
		log.severe("---------------授权开始=====");
		// TODO Auto-generated method stub
		String sessionID = iq.getSessionID();
		if (iq.getJingle() != null) {
			log.severe("---------------语音通话开始=====");
			Transmit.transmitMedia(sessionID, iq);
			log.severe("---------------语音通话结束=====");
		} else if (iq.getVideo() != null) {
			log.severe("---------------视频开始=====");
			Transmit.transmitMedia(sessionID, iq);
			log.severe("---------------视频结束=====");
		} else if (iq.getRegister() != null) {
			register(iq);
		} else if (iq.getSession() != null && iq.getSession().getX() != null
				&& iq.getSession().getX().get("action") != null) {
			UserEhcacheImpl userEhcache = new UserEhcacheImpl();
			String id = Transmit.transmitUser(sessionID);
			DispatchSupport
					.closeBiz(iq, userEhcache, BizStatus.BIZSTATUS_CLOSE);
			iq.setSessionID(id);
			commision.write(iq);
		} else if (iq.getSession() != null && iq.getSession().getX() != null) {
			/**
			 * 第一次确认暂时取消 IQ responseIQ = new IQ();
			 * responseIQ.setFrom("example.com"); responseIQ.setType("result");
			 * responseIQ.setSessionID(iq.getSessionID());
			 * responseIQ.setId(iq.getId()); commision.write(responseIQ);
			 * 
			 * Biz biz = new Biz(); commision.deportBiz(biz); UserEhcacheImpl
			 * userEhcache = new UserEhcacheImpl(); UserCache userCache =
			 * userEhcache.getUserCachebySessionId(iq.getSessionID());
			 * userCache.setBiz(biz); commision.modifyUserCache(userCache);
			 */

			HashMap<String, List<String>> map = iq.getSession().getX();
			if (map != null) {
				if (map.get("bizType") != null
						&& !"".equals(map.get("bizType").get(0)))// 有bizType的是经办端请求的
				{
					Biz biz = DispatchSupport.getBIZ(map);
					if (biz != null) {
						// biz.setBizid(userEhcache.getUserCachebySessionId(iq.getSessionID()).getBiz().getBizid());
						commision.deportBiz(biz);
						log.info("---------------持久化biz:bizID====="
								+ biz.getBizid() + "------------");
						if (commision.addSessionBiz(biz.getBizid(), System
								.currentTimeMillis(), biz.getBizTypeID())) {
							log.info("------------biz加入session池---------");
							UserCache userCache = commision.getUserCache(iq,
									biz);// 分配，得到授权端user

							if (userCache == null) {
								return;
							}
							bizHelper.grant(userCache, iq, biz);
						}
					} else {
						log.error("iq biz is null ");
					}
				}
			}
		} else {
			log.severe("iq.getSession().getX() is null");
		}
	}

	/**
	 * 分发处理message对象，特例为授权请求的元数据message，需做特别处理，填充cache中biz对象
	 */

	public void dispatch(Message message) {
		HashMap<String, List<String>> map = message.getX();

		if (map != null) {
			if (map.get(KEY_ACCPET) != null) {
				log.severe("---------------接受授权=====");
				// commision.acceptSendMessage(message, map);
				commision.acceptRespone(message);
				return;
			}
			if (map.get(KEY_REJECT) != null) {
				log.severe("---------------拒绝授权=====");
				commision.rejectRespone(message);
				// commision.rejectSendMessage(message, map);
				return;
			}
			if (map.get(KEY_CANCEL) != null) {
				log.severe("---------------取消授权=====");
				commision.acceptRespone(message);
				return;
			}
			if (map.get("screen") != null || map.get("image") != null) {
				log.severe("---------------发送图片=====");
				commision.saveTurnImage(message, map);
				// message.setSessionID(Transmit.transmitUser(message
				// .getSessionID()));
				// commision.write(message);
				return;
			}
		} else {
			log.severe("---------------发送文本开始=====");
			commision.saveTurnTextMessage(message);
			// message.setSessionID(Transmit.transmitUser(message.getSessionID()));
			// commision.write(message);
			return;
		}
	}

	public void dispatch(Presence presence) {
		// TODO Auto-generated method stub
		if (presence != null) {
			commision.modifyState(presence);
		}
	}

	public static void dispatchLogOut(String sessionID) {
		// TODO Auto-generated method stub
		EhcacheInterface ei = new UserEhcacheImpl();
		UserCache userCache = ei.getUserCachebySessionId(sessionID);
		if (userCache != null) {
			int userId = userCache.getUserid();
			ei.removeElementById(userId);
		}
	}

	public static void dispatch(String sessionID) {
		// TODO Auto-generated method stub
		ClassPathXmlApplicationContext factory = ApplicationContextFactory
				.getContext();
		ISocketException socketException = (SocketExceptionImpl) factory
				.getBean("socketExceptionImpl");
		socketException.stocketException(sessionID);
	}

	public Icommision getCommision() {
		return commision;
	}

	public void setCommision(Icommision commision) {
		this.commision = commision;
	}
}
